from datetime import timedelta, datetime

from starlette.status import HTTP_403_FORBIDDEN

import models
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, APIKeyHeader
from jose import jwt, ExpiredSignatureError, JWTError
from passlib.context import CryptContext
from typing import Union
from sqlalchemy.orm import Session
from starlette import status

from models.db import get_db

SECRET_KEY = "f22963b14a1926244a3c90fec7ec3d5c3765d0cbb3f022f91557346e47d1d6df"
ALGORITHM = "HS256"

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="v1/user/login")
# 假设 API Key 的请求头名称为 'X-API-Key'
api_key_header = APIKeyHeader(name="X-API-KEY", auto_error=False)

# 定义合法的 API Key (可以从数据库、配置文件等获取)
API_KEY = "iTbiL86ERbmwSkADNNXeHsNlC2gUMKp8_VK3q_Gyz-E"


def token_auth(token):
    """验证每个请求携带的token"""
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
    except (ExpiredSignatureError, JWTError):
        return False
    user_info: str = payload.get("sub")
    if not user_info:
        return False
    return True


def get_current_user_id(token: str) -> int:
    """获取当前用户ID"""
    payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
    user_id = payload['id']
    return int(user_id)


def get_current_user_name(token: str):
    """获取当前用户名称"""
    payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
    username = payload['sub']
    return username


async def verify_token(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)):
    """全局统一token验证"""
    if not token_auth(token):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户认证失败",
            headers={"WWW-Authenticate": "Bearer"},
        )
    db_data = db.query(models.Blacklist).filter_by(token=token).first()
    # blacklist = await blacklist_collection.find_one({'token': token})
    if db_data:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="无效的token",
            headers={"WWW-Authenticate": "Bearer"},
        )


# 验证 API Key
async def verify_api_key(api_key: str = Depends(api_key_header)):
    if api_key == API_KEY:
        return True
    elif api_key is None:
        raise HTTPException(
            status_code=HTTP_403_FORBIDDEN, detail="API KEY missing"
        )
    else:
        raise HTTPException(
            status_code=HTTP_403_FORBIDDEN, detail="Invalid API KEY"
        )


def get_password_hash(password):
    return pwd_context.hash(password)


def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)



def create_access_token(data: dict, expires_delta: Union[timedelta, None] = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt
